import { getBroadcastData, getStockdiagnosis } from '../api';
import { sleep, errorReport, sendStat } from '../utils/tools';

import {
  BroadcastType,
  BroadcastContentType,
  BroadcastStatus,
  type BroadcastContent,
  type BroadcastData,
  type CaptionData
} from '../types/vtuber';

type MethodsKey = 'listenNowBroadcast' | 'listenStatus' | 'listenHasLastLiveBroadcast';

class Broadcast {
  // 当前正在播报的内容和上一个实时解盘的内容
  private broadcastData: Record<'now' | 'last', BroadcastData>;
  // 判断是否是首次进入的localstorage的key
  private firstEnterKey: string;
  // 判断是否需要自动播放的localstorage的key
  private autoPlayKey: string;
  // 当次首次点击实时解盘
  private firstClickKey: string;
  // 当前播放状态
  private status: BroadcastStatus | void;
  // watch当前播报内容是否有变化
  private executeListen: (params: MethodsKey, ...params2) => void;
  // 随机播报的序号
  private randomIndex: number;
  // 下一条播报的接口的参数
  private params: {
    type: string;
    id: string;
  };
  constructor({
    listenNowBroadcast,
    listenStatus,
    listenHasLastLiveBroadcast
  }: Record<string, Function>) {
    this.broadcastData = {
      now: void 0,
      last: void 0
    };
    // 执行监听
    this.executeListen = (methodsKey: MethodsKey, ...params) => {
      // 工厂模式
      const methodsOptions = {
        listenNowBroadcast: listenNowBroadcast.bind(this, this.deepClone(this.broadcastData.now)),
        listenStatus: listenStatus.bind(this, this.status),
        listenHasLastLiveBroadcast: listenHasLastLiveBroadcast.bind(this, !!this.broadcastData.last)
      };
      methodsOptions[methodsKey](...params);
    };
    this.status = void 0;
    this.params = {
      type: '',
      id: ''
    };
    this.randomIndex = 0;
    this.getuseid().then((userid) => {
      this.firstEnterKey = `b2c-high-level-paid-vtuber-firstentry-${userid}`;
      this.autoPlayKey = `b2c-high-level-paid-vtuber-autoplay-${userid}`;
      this.firstClickKey = `b2c-high-level-paid-vtuber-firstClickKey-${userid}`;
      if (this.isFirstEnter()) {
        // 首次进入
        this.firstEnter();
      } else if (!this.getAutoPlayStatus()) {
        // 非自动播放
        this.notAutoPlay();
      } else {
        // 自动播放
        this.autoplay();
      }
    });
  }
  private getuseid(): Promise<unknown> {
    return new Promise((resolve) => {
      if (!window.API) {
        resolve('');
      }
      window.API.use({
        method: 'Passport.get',
        data: 'userid',
        success: (result: string) => {
          resolve(result);
        },
        notClient: () => {
          resolve('');
        }
      });
    }).catch((error) => {
      errorReport({
        name: `客户端协议获取userid方法报错 method:'Passport.get',data:'userid' ${error.name}`,
        message: error.message,
        stack: error.stack
      });
    });
  }
  // 判断是否是首次点击实时解盘
  private isFirstClick() {
    return !window.sessionStorage.getItem(this.firstClickKey);
  }
  // 设置不是首次点击实时解盘
  private setFirstClick() {
    window.sessionStorage.setItem(this.firstClickKey, '1');
  }
  // 判断是否是首次进入
  private isFirstEnter() {
    return !window.localStorage.getItem(this.firstEnterKey);
  }
  // 是否是自动播放
  public getAutoPlayStatus() {
    return !!window.localStorage.getItem(this.autoPlayKey);
  }
  // 首次进入
  private firstEnter() {
    this.broadcastData.now = {
      index: 0,
      broadcastType: BroadcastType.ExaminingStock,
      broadcastContents: [
        {
          contentType: BroadcastContentType.Greeting,
          content: {
            // 已经播报过的内容
            removedValue: '',
            // 剩余内容
            remainValue:
              '您好，我是您的专属AI助手。我现在可以提供实时解盘和股票诊断功能，先来试试实时解盘吧！',
            // 当前播报内容
            nowValue: ''
          }
        },
        {
          contentType: BroadcastContentType.Button,
          content: {
            // 已经播报过的内容
            removedValue: '',
            // 剩余内容
            remainValue: '',
            // 当前播报内容
            nowValue: ''
          }
        }
      ]
    };
    this.executeListen('listenNowBroadcast');
  }
  // 自动播放
  private autoplay() {
    this.status = BroadcastStatus.Autoplay;
    this.executeListen('listenStatus');
    this.push({
      content: {
        removedValue: '',
        remainValue: '最新解盘为您自动报送',
        nowValue: ''
      },
      contentType: BroadcastContentType.Greeting
    });
    this.setNextBroadcastData();
    sendStat('_cpsy_zxhrk_zdbf');
  }
  // 非自动播放
  private notAutoPlay() {
    this.status = BroadcastStatus.NotAutoplay;
    this.executeListen('listenStatus');
    this.broadcastTime();
  }
  // 从接口获取最新一条播报信息
  private getBroadcastData(): Promise<BroadcastContent | void> {
    return getBroadcastData(this.params)
      .then((res) => {
        if (res.status_code) {
          throw new Error(
            `status_code报错,status_code为${res.status_code},status_msg为${res.status_msg}`
          );
        }
        const data = res.data;
        if (!data) {
          return void 0;
        }
        const { type, id } = data;
        this.params = {
          type: `${type}`,
          id
        };
        return {
          contentType: BroadcastContentType.Vtuber,
          content: {
            remainValue: res.data.content,
            removedValue: '',
            nowValue: ''
          }
        };
      })
      .catch((error) => {
        errorReport({
          name: `获取最新一条播报信息接口报错 ${error.name}`,
          message: error.message,
          stack: error.stack
        });
      });
  }
  // 将获取的播报信息插入到当前信息末尾
  private setNextBroadcastData() {
    this.getBroadcastData().then((data) => {
      if (!data) {
        return;
      }
      this.push(data);
    });
  }
  // 获取诊股结果
  private getStockdiagnosis(
    stock_code: string,
    stock_name: string
  ): Promise<BroadcastContent[] | void> {
    return getStockdiagnosis({ stock_code })
      .then((res) => {
        if (res.status_code) {
          throw new Error(
            `status_code报错,status_code为${res.status_code},status_msg为${res.status_msg}`
          );
        }
        const tempArr = [
          {
            contentType: BroadcastContentType.User,
            content: {
              remainValue: stock_name,
              removedValue: '',
              nowValue: ''
            }
          },
          {
            contentType: BroadcastContentType.Vtuber,
            content: {
              remainValue: res?.data?.fundamental_analysis,
              removedValue: '',
              nowValue: ''
            }
          },
          {
            contentType: BroadcastContentType.Vtuber,
            content: {
              remainValue: res?.data?.market_analysis,
              removedValue: '',
              nowValue: ''
            }
          },
          {
            contentType: BroadcastContentType.Vtuber,
            content: {
              remainValue:
                (res?.data?.ai_analyses?.capital_analysis || '') +
                (res?.data?.ai_analyses?.activity_analysis || '') +
                (res?.data?.ai_analyses?.trend_analysis || ''),
              removedValue: '',
              nowValue: ''
            }
          },
          {
            contentType: BroadcastContentType.Vtuber,
            content: {
              remainValue: res?.data?.operate_advice,
              removedValue: '',
              nowValue: ''
            }
          },
          {
            contentType: BroadcastContentType.Vtuber,
            content: {
              remainValue:
                '诊断报告数据来源于客观数据分析，影响股价的因素很多，诊断结果仅供参考，不构成投资建议，投资者需自主做出投资决策并承担投资风险，股市有风险，投资需谨慎。',
              removedValue: '',
              nowValue: ''
            }
          }
        ];
        return tempArr.filter((item) => item.content.remainValue);
      })
      .catch((error) => {
        errorReport({
          name: `获取诊股结果的接口报错 ${error.name}`,
          message: error.message,
          stack: error.stack
        });
      });
  }
  // 将获取的诊股信息插入到当前信息末尾
  private setNextStockdiagnosis(stock_code: string, stock_name: string) {
    this.getStockdiagnosis(stock_code, stock_name).then((data) => {
      if (!data) {
        return;
      }
      this.push(...data);
    });
  }
  // 同一part的下一条
  public next() {
    this.broadcastData.now.index++;
    this.executeListen('listenNowBroadcast', true);
  }
  //   下一部分
  public nextPart({
    broadcastType,
    stock_code,
    stock_name,
    needJudgeFirstClick = false
  }: {
    broadcastType: BroadcastType;
    stock_code?: string;
    stock_name?: string;
    needJudgeFirstClick?: boolean;
  }) {
    // 当前播报的是实时解盘,需要将其存到上一次的播报内容
    if (this.broadcastData.now.broadcastType === BroadcastType.LiveInformation) {
      const { index, broadcastContents } = this.broadcastData.now;
      if (!broadcastContents.length) {
        return;
      }
      const { nowValue, remainValue, removedValue } = broadcastContents[index].content;

      this.broadcastData.now.broadcastContents[index].content = {
        removedValue,
        nowValue: '',
        remainValue: nowValue + remainValue
      };
      // 需要将欢迎语和用户发言过滤掉
      this.broadcastData.now.broadcastContents = this.broadcastData.now.broadcastContents.filter(
        ({ contentType }, i) => {
          if (![BroadcastContentType.Greeting, BroadcastContentType.User].includes(contentType)) {
            return true;
          } else {
            // 如果将正在读或者已经读过的欢迎语去除，需要将index减一
            if (i <= index && this.broadcastData.now.index) {
              this.broadcastData.now.index--;
            }
            return false;
          }
        }
      );
      this.broadcastData.last = this.deepClone(this.broadcastData.now);
      this.executeListen('listenHasLastLiveBroadcast');
    }
    if (broadcastType === BroadcastType.ExaminingStock) {
      this.getStockdiagnosis(stock_code, stock_name).then((data) => {
        if (!data) {
          return;
        }
        this.broadcastData.now = {
          index: 0,
          broadcastType: BroadcastType.ExaminingStock,
          broadcastContents: data
        };
        this.executeListen('listenNowBroadcast');
      });
    } else {
      const broadcastContents = this.broadcastData.last?.broadcastContents;
      if (
        broadcastContents?.[broadcastContents?.length - 1]?.content?.remainValue &&
        this.broadcastData.now.broadcastType === BroadcastType.ExaminingStock
      ) {
        // 如果有last没有播放完，则需要继续播放
        this.continueLastLiveBroadcast();
      } else {
        // 需要间隔1s再开始播报
        Promise.all([this.getBroadcastData(), sleep(1000)])
          .then(([data]) => {
            if (needJudgeFirstClick) {
              const broadcastContents: BroadcastContent[] = !data
                ? [
                    {
                      contentType: BroadcastContentType.Greeting,
                      content: {
                        nowValue: '',
                        remainValue: '抱歉，暂时没有新的解盘',
                        removedValue: ''
                      }
                    }
                  ]
                : [
                    {
                      contentType: BroadcastContentType.Greeting,
                      content: {
                        nowValue: '',
                        remainValue: '好的，来看看今天的实时解盘',
                        removedValue: ''
                      }
                    },
                    data
                  ];
              this.broadcastData.now = {
                broadcastContents,
                index: 0,
                broadcastType: BroadcastType.LiveInformation
              };
            } else {
              if (!data) {
                return;
              }
              this.broadcastData.now = {
                index: 0,
                broadcastType: BroadcastType.LiveInformation,
                broadcastContents: [data]
              };
            }
            this.executeListen('listenNowBroadcast');
          })
          .finally(() => {
            this.setFirstClick();
          });
      }
    }
  }
  // 首次进入点击实时解盘按钮
  public firstEnterClickExamine() {
    this.status = BroadcastStatus.IsFirstEnter;
    this.executeListen('listenStatus');
    window.localStorage.setItem(this.firstEnterKey, '1');
    sendStat('_dhym_ssjp');
    this.broadcastData.now = {
      index: 1,
      broadcastType: BroadcastType.LiveInformation,
      broadcastContents: [
        {
          contentType: BroadcastContentType.Greeting,
          content: {
            // 已经播报过的内容
            removedValue:
              '您好，我是您的专属AI助手。我现在可以提供实时解盘和股票诊断功能，先来试试实时解盘吧！',
            // 剩余内容
            remainValue: '',
            // 当前播报内容
            nowValue: ''
          }
        },
        {
          contentType: BroadcastContentType.User,
          content: {
            // 已经播报过的内容
            removedValue: '',
            // 剩余内容
            remainValue: '实时解盘',
            // 当前播报内容
            nowValue: ''
          }
        },
        {
          contentType: BroadcastContentType.Greeting,
          content: {
            // 已经播报过的内容
            removedValue: '',
            // 剩余内容
            remainValue: '好的，已默认为您开启自动播报，有解盘更新时会自动播放～',
            // 当前播报内容
            nowValue: ''
          }
        },
        {
          contentType: BroadcastContentType.Greeting,
          content: {
            // 已经播报过的内容
            removedValue: '',
            // 剩余内容
            remainValue: '先来看看今天的实时解盘',
            // 当前播报内容
            nowValue: ''
          }
        }
      ]
    };
    this.setNextBroadcastData();
  }
  // 结束播报
  public endBroadcast(needTag: boolean = true) {
    const braodcastData = needTag
      ? {
          now: {
            index: 0,
            broadcastType: BroadcastType.ExaminingStock,
            broadcastContents: [
              {
                content: {
                  remainValue: '好的，点击下方功能可以随时招呼我',
                  removedValue: '',
                  nowValue: ''
                },
                contentType: BroadcastContentType.Greeting
              }
            ]
          },
          last: void 0
        }
      : {
          now: {
            index: 0,
            broadcastType: BroadcastType.ExaminingStock,
            broadcastContents: []
          },
          last: void 0
        };
    this.broadcastData = braodcastData;
    this.executeListen('listenHasLastLiveBroadcast');
    this.executeListen('listenNowBroadcast');
  }
  // 设置自动播放
  public toggleAutoPlay() {
    const autoplayFlag = this.getAutoPlayStatus() ? '' : '1';
    window.localStorage.setItem(this.autoPlayKey, autoplayFlag);
  }
  // 继续上一次实时解盘的播报内容
  private continueLastLiveBroadcast() {
    this.broadcastData.last.broadcastContents.unshift({
      contentType: BroadcastContentType.Greeting,
      content: {
        removedValue: '',
        remainValue: '好的，让我们回到解盘',
        nowValue: ''
      }
    });
    this.broadcastData.now = this.deepClone(this.broadcastData.last);
    this.executeListen('listenNowBroadcast');
  }
  // 当前播报内容往后push
  private push(...broadcastContent: BroadcastContent[]) {
    if (this.broadcastData.now) {
      this.broadcastData.now.broadcastContents.push(...broadcastContent);
    } else {
      this.broadcastData.now = {
        index: 0,
        broadcastType: BroadcastType.LiveInformation,
        broadcastContents: broadcastContent
      };
    }
    this.executeListen('listenNowBroadcast', true);
  }
  // 播放时修改字幕
  public playChangeCaption({ remainValue, removedValue, nowValue }: CaptionData) {
    const index = this.broadcastData.now.index;
    this.broadcastData.now.broadcastContents[index].content = {
      remainValue,
      removedValue,
      nowValue
    };
  }
  // 深克隆
  private deepClone<T>(obj: T): T {
    try {
      return JSON.parse(JSON.stringify(obj));
    } catch (error) {
      errorReport({
        name: `深克隆对象${obj}时候发生错误 ${error.name}`,
        message: error.message,
        stack: error.stack
      });
    }
  }
  // 根据时间得到问候语
  private getTimeGreeting() {
    const date = new Date();
    const hour = date.getHours();
    let greeting: string;
    switch (true) {
      case hour >= 8 && hour < 11:
        greeting = '上午好';
        break;
      case hour >= 11 && hour < 13:
        greeting = '中午好';
        break;
      case hour >= 13 && hour < 17:
        greeting = '下午好';
        break;
      case hour >= 17 && hour <= 23:
        greeting = '晚上好';
        break;
      default:
        greeting = '你好';
        break;
    }
    return greeting;
  }
  // 清屏状态下，点击AI助手随机播报
  public randomBroadcast() {
    const remainValues = [
      `${this.getTimeGreeting()}。有什么可以帮您？`,
      '要不要试试资讯速递？',
      '输入股票有惊喜哦！'
    ];
    this.broadcastData.now = {
      index: 0,
      broadcastType: BroadcastType.ExaminingStock,
      broadcastContents: [
        {
          contentType: BroadcastContentType.Greeting,
          content: {
            nowValue: '',
            removedValue: '',
            remainValue: remainValues[this.randomIndex % remainValues.length]
          }
        }
      ]
    };
    this.randomIndex++;
    this.executeListen('listenNowBroadcast');
  }
  // 最大化欢迎语
  public welcomeBroadcast() {
    if (this.status === void 0) {
      this.firstEnter();
    } else {
      this.broadcastTime();
    }
  }
  // 时间欢迎语
  private broadcastTime() {
    this.broadcastData.now = {
      index: 0,
      broadcastType: BroadcastType.ExaminingStock,
      broadcastContents: [
        {
          content: {
            removedValue: '',
            remainValue: `${this.getTimeGreeting()}，我是您的专属AI助手。有什么可以帮您？`,
            nowValue: ''
          },
          contentType: BroadcastContentType.Greeting
        }
      ]
    };
    this.executeListen('listenNowBroadcast');
  }
}
export default Broadcast;
